"""
项目管理系统的Program模型DAO层
"""
from datetime import datetime
from app.Models.Goal.GoalModel import Goal
from app.Services.GoalServices import GoalServices
from app.db import db
from app.Models.Work.Program import Program

class ProgramDAO:
    @staticmethod
    def create_program(user_id, program_name, program_desc, program_status, 
                      goal_id=None, attachment=None):
        """
        创建新项目
        :param user_id: 用户ID
        :param program_name: 项目名称
        :param program_desc: 项目描述
        :param program_status: 项目状态
        :param goal_id: 目标ID（可选）
        :param attachment: 附件路径（可选）
        :return: (bool, 项目对象/错误信息)
        """
        try:
            now = datetime.now()
            program = Program(
                user_id=user_id,
                program_name=program_name,
                program_desc=program_desc,
                program_status=program_status,
                goal_id=goal_id,
                attachment=attachment,
                create_time=now,
                update_time=now
            )
            db.session.add(program)
            db.session.commit()
            return True, program
        except Exception as e:
            db.session.rollback()
            return False, str(e)

    @staticmethod
    def get_program_by_id(program_id):
        """
        通过ID获取项目
        :param program_id: 项目ID
        :return: (bool, 项目对象/错误信息)
        """
        try:
            program = Program.query.get(program_id)
            if program:
                return True, program
            return False, "项目不存在"
        except Exception as e:
            return False, str(e)



    @staticmethod
    def get_programs_by_user(user_id, page=1, per_page=10):
        """
        获取用户的所有项目（分页），并包含对应的goal_name
        :param user_id: 用户ID
        :param page: 页码
        :param per_page: 每页数量
        :return: (bool, 包含goal_name的项目列表/错误信息)
        """
        try:
            pagination = Program.query.filter_by(user_id=user_id) \
                .order_by(Program.update_time.desc()) \
                .paginate(page=page, per_page=per_page, error_out=False)
            
            items_with_goal = []
            for program in pagination.items:
                goal_name = None
                # 只有当goal_id存在时才查询
                if program.goal_id:
                    success, _, goal_data = GoalServices.GoalService.get_goal_by_id(program.goal_id)
                    if success and goal_data:
                        goal_name = goal_data.get('goal_name')  # 使用get避免KeyError
                
                program_dict = {
                    'id': program.id,
                    'user_id': program.user_id,
                    'program_name': program.program_name,
                    'program_desc': program.program_desc,
                    'program_status': program.program_status,
                    'goal_id': program.goal_id,
                    'goal_name': goal_name,  # 空值直接返回None
                    'create_time': program.create_time,
                    'update_time': program.update_time,
                    'attachment': program.attachment
                }
                items_with_goal.append(program_dict)
            
            return True, items_with_goal
        except Exception as e:
            return False, str(e)
    @staticmethod
    def get_all_programs(page=1, per_page=10):
        """
        获取所有项目（分页）
        :param page: 页码
        :param per_page: 每页数量
        :return: (bool, 分页对象/错误信息)
        """
        try:
            pagination = Program.query.order_by(Program.update_time.desc()).paginate(
                page=page, per_page=per_page, error_out=False)
            return True, pagination
        except Exception as e:
            return False, str(e)

    @staticmethod
    def update_program(program_id, **kwargs):
        """
        更新项目信息
        :param program_id: 项目ID
        :param kwargs: 要更新的字段（program_name, program_desc, program_status, goal_id, attachment）
        :return: (bool, 更新后的项目对象/错误信息)
        """
        try:
            program = Program.query.get(program_id)
            if not program:
                return False, "项目不存在"
            
            # 更新字段
            allowed_fields = ['program_name', 'program_desc', 'program_status', 'goal_id', 'attachment']
            for key, value in kwargs.items():
                if key in allowed_fields and value is not None:
                    setattr(program, key, value)
            
            # 更新时间
            program.update_time = datetime.now()
            
            db.session.commit()
            return True, program
        except Exception as e:
            db.session.rollback()
            return False, str(e)

    @staticmethod
    def delete_program(program_id):
        """
        删除项目
        :param program_id: 项目ID
        :return: (bool, 成功信息/错误信息)
        """
        try:
            program = Program.query.get(program_id)
            if not program:
                return False, "项目不存在"
            
            db.session.delete(program)
            db.session.commit()
            return True, "项目删除成功"
        except Exception as e:
            db.session.rollback()
            return False, str(e)

    @staticmethod
    def get_programs_by_status(program_status, page=1, per_page=10):
        """
        根据状态获取项目
        :param program_status: 项目状态
        :param page: 页码
        :param per_page: 每页数量
        :return: (bool, 分页对象/错误信息)
        """
        try:
            pagination = Program.query.filter_by(program_status=program_status).order_by(
                Program.update_time.desc()).paginate(page=page, per_page=per_page, error_out=False)
            return True, pagination
        except Exception as e:
            return False, str(e)

    @staticmethod
    def get_programs_by_goal(goal_id, page=1, per_page=10):
        """
        根据目标ID获取项目
        :param goal_id: 目标ID
        :param page: 页码
        :param per_page: 每页数量
        :return: (bool, 分页对象/错误信息)
        """
        try:
            pagination = Program.query.filter_by(goal_id=goal_id).order_by(
                Program.update_time.desc()).paginate(page=page, per_page=per_page, error_out=False)
            return True, pagination
        except Exception as e:
            return False, str(e)

    @staticmethod
    def search_programs(keyword, page=1, per_page=10):
        """
        搜索项目（按名称或描述）
        :param keyword: 搜索关键词
        :param page: 页码
        :param per_page: 每页数量
        :return: (bool, 分页对象/错误信息)
        """
        try:
            pagination = Program.query.filter(
                db.or_(
                    Program.program_name.ilike(f'%{keyword}%'),
                    Program.program_desc.ilike(f'%{keyword}%')
                )
            ).order_by(Program.update_time.desc()).paginate(page=page, per_page=per_page, error_out=False)
            return True, pagination
        except Exception as e:
            return False, str(e)